[アップデート] Amazon CloudWatch のアラームで、実行アクションに Lambda 関数を直接指定出来るようになりました
いわさです。
Amazon CloudWatch のアラームではアラームの状態変更をトリガーとしたアクションを実行することが出来ます。
これまでは Amazon SNS への通知、Auto Scaling アクション(容量の変更)の実行、EC2 アクション(停止や再起動)、SSM アクション(OpsItem/インシデントの作成)を行うことが出来ていました。
本日のアップデートでこのアクションで新たに Lambda 関数を実行出来るようになりました。
従来はアラート発生時に Lambda によるカスタムアクションを実行したい場合は Amazon SNS トピックを経由して Lambda をサブスクライブさせて間接的に呼び出す必要がありましたが、直接統合出来るようになりました。
設定方法
設定方法は他のアクションを設定する流れと同じで、対象の CloudWatch Alarm のアクション設定画面で設定を行います。
次のように新たに「Lambda アクション」が追加されていることが確認出来ます。
参考までに、2023 年 11 月 21 日時点のアクション設定画面はこちらの記事で確認出来ます。
関数を設定する
適当な関数を作成し、アクションに指定みましょう。
実行されたか確認出来れば良いのでデフォルトで作成します。どういうイベントデータを受信するのか確認したいのでログ出力コードくらいは追加しました。
アクションで設定出来るのは次のような項目です。
従来同様にアラーム状態の何をトリガーにするのかを選択します。
また、この機能は別アカウントの関数呼び出しにも対応しています。権限周りは後述します。
あとは関数を指定し、オプションでバージョンあるいはエイリアスを指定出来ます。ありがたい。
CloudWatch アラームとしての設定はこれで OK です。
Lambda アクションを設定しアラームを発生させてみた
適当な関数をアクションに設定したので早速、次のように AWS CLI 経由で手動でアラーム状態に変更してみました。
アラーム状態に変わりました。
しかし、アラームの履歴画面を確認してみると次のエラーが発生していました。
アクション arn:aws:lambda:ap-northeast-1:123456789023:function:hoge1223lambda の実行に失敗しました。エラーが発生しました: "CloudWatch Alarms is not authorized to perform: lambda:InvokeFunction on the resource because no resource-based policy allows the lambda:InvokeFunction action"
Lambda 側にリソースベースポリシーが必要
そりゃそうかという感じですが Lambda 実行の権限周りを何も指定していませんでした。
アラーム側でサービスロールの指定はないので、Lambda 関数側でリソースベースでのポリシー設定が必要です。
Lambda のアクセス権限機能で次のようにリソースベースポリシーを追加します。
プリンシパルはlambda.alarms.cloudwatch.amazonaws.com
になるようなのでこちらを指定しました。
もう一度アラーム状態を変更してみると、次は Lambda 関数のアクションが正常に実行されていることが確認出来ました。
Lambda 側のメトリクスでも実行されていることが確認出来ますね。
イベントログ
CloudWatch アラームから実行されるときのイベントログ内容を確認してみました。
トリガーされた時のアラームの状態だけでなく、変更前の状態も送信されていますね。
アラームで構成されている条件なども確認出来ました。
{ "source": "aws.cloudwatch", "alarmArn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm:hoge1223vcpualarm", "accountId": "123456789012", "time": "2023-12-22T22:15:48.857+0000", "region": "ap-northeast-1", "alarmData": { "alarmName": "hoge1223vcpualarm", "state": { "value": "ALARM", "reason": "test", "timestamp": "2023-12-22T22:15:48.857+0000" }, "previousState": { "value": "OK", "reason": "Threshold Crossed: 1 out of the last 1 datapoints [0.0 (22/12/23 22:00:00)] was not greater than the threshold (100.0) (minimum 1 datapoint for ALARM -> OK transition).", "reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2023-12-22T22:05:15.507+0000\",\"startDate\":\"2023-12-22T22:00:00.000+0000\",\"statistic\":\"Average\",\"period\":300,\"recentDatapoints\":[0.0],\"threshold\":100.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2023-12-22T22:00:00.000+0000\",\"sampleCount\":5.0,\"value\":0.0}]}", "timestamp": "2023-12-22T22:05:15.510+0000" }, "configuration": { "metrics": [ { "id": "b2c649c4-bbdd-9e1f-e239-9535e3c67e12", "metricStat": { "metric": { "namespace": "AWS/Usage", "name": "ResourceCount", "dimensions": { "Resource": "vCPU", "Service": "Fargate", "Type": "Resource", "Class": "Standard/OnDemand" } }, "period": 300, "stat": "Average" }, "returnData": true } ] } } }
さいごに
本日は Amazon CloudWatch のアラームで、実行アクションに Lambda 関数を直接指定出来るようになったので使ってみました。
今までカスタムアクションを実行したい場合は Amazon SNS を経由する必要があったのですが、直接 Lambda を統合出来るようになったので、冗長な SNS トピックを除外出来そうです。リトライなどアクションの要件によっては引き続き SNS を間に挟むケースもありそうですけど。
Lambda のリソースベースポリシーの設定忘れのないように気をつけましょう。